import {Promise} from 'es6-promise';
import * as utils from "./utils";
import {ErrCode} from "./error.code";
let urlencode = require('urlencode');

export interface AlipayTrans {
    subject: string,
    body: string,
    amount: number,
    transId: string
}

const private_key = '-----BEGIN RSA PRIVATE KEY-----\n' +
    '-----END RSA PRIVATE KEY-----\n';

const rsa_public =
    '-----BEGIN PUBLIC KEY-----\n' +
    '-----END PUBLIC KEY-----';

export const AlipayCfg = {
    partner: '22222',
    seller: '@...',
    rsa_private: private_key,
    rsa_public: rsa_public,
    service: 'mobile.securitypay.pay',
    payment_type: '1',
    charset: 'utf-8',
    expiration: '30m',
    sign_type: 'RSA',
    notifyUrl: 'http://xxxx'
};

export default class Alipay {

    constructor() {}

    private getTransInfo(info: AlipayTrans): string{
        return [
            'partner="' +  AlipayCfg.partner + "\"",
            'seller_id="' +  AlipayCfg.seller + "\"",
            'out_trade_no="' +  info.transId + "\"",
            'subject="' +  info.subject + "\"",
            'body="' +  info.body + "\"",
            'total_fee="' +  info.amount + "\"",
            'notify_url="' +  AlipayCfg.notifyUrl + "\"",
            'service="' +  AlipayCfg.service + "\"",
            'payment_type="' +  AlipayCfg.payment_type + "\"",
            '_input_charset="' +  AlipayCfg.charset + "\"",
            'it_b_pay="' +  AlipayCfg.expiration + "\"",
        ].join('&');
    }


    private sign(content){
        return utils.sha1WithRsa(content, AlipayCfg.rsa_private);
    }

    getTransInfoStr(info: AlipayTrans): Promise<string>{
        let content = this.getTransInfo(info);
        let that = this;
        return new Promise(function (resolve, reject) {
            let sign = that.sign(content).toString();
            resolve(content + '&sign="' + urlencode(sign) + '"&sign_type="' +  AlipayCfg.sign_type  + "\"");
        });
    }

    verifySign(info: Object): Promise<any>{
        return Promise.resolve().then(() => {
            if(info['sign_type'] !== 'RSA' || !info['sign']){
                return Promise.reject({err_code: ErrCode.ArgsInvalid});
            }

            let content = this.groupVerifyInfo(info);
            let result = utils.verifyRsa(content, AlipayCfg.rsa_public, info['sign']);

            return Promise.resolve(result);
        });
    }

    private groupVerifyInfo(info: Object){
        var paramsToSign = [];
        for(var name in info) {
            if(name != 'sign' && name != 'sign_type') {
                paramsToSign.push(name + '=' + info[name]);
            }
        }
        paramsToSign.sort();
        return paramsToSign.join('&');
    }

    name() { return 'Alipay'; }
}